use crate::sql::parse::ast;
use crate::sql::parse::ast::{Statement};
use crate::sql::plan::{Node, Plan};
use crate::sql::schema;
use crate::sql::schema::Table;
use crate::sql::types::Value;

pub struct Planner;

impl Planner {
    pub fn new() -> Self {
        Self {}
    }
    pub fn build(&mut self, stat: ast::Statement) -> Plan {
        Plan(self.build_statement(stat))
    }
    fn build_statement(&self, stat: ast::Statement) -> Node {
        match stat {
            Statement::CreateTable { name, columns } => Node::CreateTable {
                schema: Table {
                    name,
                    columns: columns.into_iter().map(|c| {
                        let nullable = c.nullable.unwrap_or(true);
                        let default = match c.default {
                            Some(expr) => Some(Value::from_expression(expr)),
                            None if nullable => Some(Value::Null),
                            None => None
                        };
                        schema::Column {
                            name: c.name,
                            datatype: c.datatype,
                            nullable,
                            default,
                        }
                    }).collect()
                }
            },
            Statement::Insert { table_name, columns, values } => Node::Insert {
                table_name,
                columns: columns.unwrap_or_default(),
                values
            },
            Statement::Select { table_name } => Node::Scan {
                table_name
            }
        }
    }
}